package cn.itcast.wanxinp2p.account.service.impl;


import cn.itcast.wanxinp2p.account.entity.Account;
import cn.itcast.wanxinp2p.account.mapper.AccountMapper;
import cn.itcast.wanxinp2p.account.service.AccountService;
import cn.itcast.wanxinp2p.common.DTO.account.AccountDTO;
import cn.itcast.wanxinp2p.common.DTO.account.AccountLoginDTO;
import cn.itcast.wanxinp2p.common.DTO.account.AccountRegisterDTO;
import cn.itcast.wanxinp2p.common.domain.AccountErrorCode;
import cn.itcast.wanxinp2p.common.domain.RestResponse;
import cn.itcast.wanxinp2p.common.exception.BusinessException;
import cn.itcast.wanxinp2p.common.util.PasswordUtil;
import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.dromara.hmily.annotation.Hmily;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import java.util.HashMap;

@Slf4j
@Service
public class AccountServiceImpl implements AccountService {

    @Autowired
    private RestTemplate restTemplate;



    @Autowired
    private AccountMapper accountMapper;


    @Value("${sms.url}")
    private String smsurl;

    @Override
    public RestResponse getSMSCode(String mobile) {
        //TODO
        // 发起远程请求调用 短信微服务 发送短信   RestTemplate
        // http://localhost:56085/sailing/generate?effectiveTime=300&name=sms
        // {"mobile":"13566668888"}

        /*返回数据：直接将短信服务的结果返回即可
            {
                "code": 0,
                "msg": "",
                "result": {
                    "key": "sms:70ba933b095b4b5c90ee314045fd9003",
                    "content": null
                }
            }
         */
        String url=smsurl+"generate?effectiveTime=300&name=sms";

        /*转换为json类型,短信微服务需要的是json格式而不是字符串*/
        HashMap<String, String> map = new HashMap<>();
        map.put("mobile",mobile);
        Object o = JSON.toJSON(map);

        /*返回*/
        return restTemplate.postForEntity(url, o, RestResponse.class).getBody();

    }



    @Override
    public Integer checkMobile(String mobile, String key, String code) {
/*        业务逻辑：
        1、远程调用 短信微服务 校验验证码是否正确
        Post请求：
        http://localhost:56085/sailing/verify?name=sms&verificationKey=sms:70ba933b095b4b5c90ee314045fd9003&verificationCode=707339
        根据解决判断验证码校验是否成功
        2、如果验证码正确，还需要根据手机号 去 account 表中查询手机号是否存在，如果不存在，给前端返回错误信息*/

        String url=smsurl+"verify?name=sms&verificationKey="+key+"&verificationCode="+code;

        RestResponse restResponse = restTemplate.postForEntity(url, null, RestResponse.class).getBody();



//        Boolean result = (Boolean) restResponse.getResult();

        if (!restResponse.isSuccessful()){
            throw new BusinessException(AccountErrorCode.E_140152);
        }

        Account account= accountMapper.countByMobile(mobile);
        if (account==null){
            return 0;
        }else {
            return 1;
        }


    }

    /**
     * 账户注册
     * @param registerDTO 注册信息
     * @return
     */
    @Override
    @Hmily(confirmMethod = "confirmRegister", cancelMethod = "cancelRegister")
    public AccountDTO register(AccountRegisterDTO registerDTO) {
        //TODO

        Account account = new Account();

        BeanUtils.copyProperties(registerDTO,account);

        /*在密码不为空的情况下去做加盐操作*/
        if (account.getPassword()!=null){
            account.setSalt(PasswordUtil.generate(account.getPassword()));
        }
        /*添加什么端的b和c端*/
        account.setDomain("c");
        /*根据电话号码查询是否存在该数据*/
        Account account1 = accountMapper.countByMobile(registerDTO.getMobile());
        if (account1!=null){
            throw new BusinessException(AccountErrorCode.E_130101);
        }
        /*根据名字查询是否存在该数据*/
        Account account2 = accountMapper.countByUserName(registerDTO.getUsername());

        if (account2!=null){
            throw new BusinessException(AccountErrorCode.E_130101);
        }

        /*存储数据*/
        accountMapper.register(account);

        /**/
        AccountDTO accountDTO = new AccountDTO();
        BeanUtils.copyProperties(account,accountDTO);
        return accountDTO;
    }
    public void confirmRegister(AccountRegisterDTO registerDTO) {
        log.info("execute confirmRegister");
    }

    public void cancelRegister(AccountRegisterDTO registerDTO) {
        log.info("execute cancelRegister");
        //TODO 删除账号
        accountMapper.deleteBymobile(registerDTO.getMobile());
    }



    @Value("${sms.enable}")
    private boolean smsEnable;

    @Override
    public AccountDTO login(AccountLoginDTO accountLoginDTO) {
        //1、查询用户，注意此处需要根据前端传递的 AccountLoginDTO的domain做判断：
        //  如果值是 c 表示是c端用户，需要根据手机号查询
        //  否则是b端用户，需要根据用户名查询

        String domain = accountLoginDTO.getDomain();

        Account account = new Account();

        /*判断是不是c端用户*/
        if ("c".equals(domain)){
            /*通过手机号查询,1为有0为无*/
             account = accountMapper.countByMobile(accountLoginDTO.getMobile());
        }
        /*如果为b端*/
        if ("b".equals(domain)){
             account= accountMapper.countByUserName(accountLoginDTO.getUsername());
        }
        //2、判断用户是否存在，如果不存在，直接抛出 AccountErrorCode.E_130104 异常

        System.out.println(account);

        if (account==null){
            throw new BusinessException(AccountErrorCode.E_130104);
        }

        AccountDTO accountDTO = new AccountDTO();
        BeanUtils.copyProperties(account,accountDTO);

        //3、如果 smsEnable=true ，说明是短信验证码登录，不做密码校验。直接返回
        if (smsEnable){
            return accountDTO;
        }


        //4、验证密码，如果密码错误则抛出 AccountErrorCode.E_130105 异常

        String password = account.getPassword();
        String password1 = accountLoginDTO.getPassword();

        if (!password.equals(password1)){
            throw new BusinessException(AccountErrorCode.E_130105);
        }
        return accountDTO;
    }

}
